package com.cuz.daileetcode.bst;

import java.util.*;

/**
 * @author cuzz
 * @version 1.0
 * @description: 二叉搜索树的节点
 * @date 21:48 2022/1/12
 **/
public class BinarySearchTreeNode<K, V> {

    /**
     * 键
     */
    private K key;
    /***
     * 值list 允许存在多个相同的值
     */
    private List<V> valueList;
    /***
     * 左树
     */
    private BinarySearchTreeNode<K, V> left;
    /***
     * 右树
     */
    private BinarySearchTreeNode<K, V> right;

    private BinarySearchTreeNode() {
    }

    public static <K, V> BstNodeBuilder<K, V> builder() {
        return new BstNodeBuilder<>();
    }

    public static class BstNodeBuilder<K, V> {
        private K key;
        private LinkedList<V> valueList;

        public BstNodeBuilder<K, V> key(K key) {
            this.key = Objects.requireNonNull(key, "键不可为空");
            return this;
        }

        public BstNodeBuilder<K, V> value(V value) {
            if (valueList == null) {
                valueList = new LinkedList<>();
            }
            valueList.addLast(value);
            return this;
        }

        public BinarySearchTreeNode<K, V> build() {
            BinarySearchTreeNode<K, V> node = new BinarySearchTreeNode<>();
            node.key = this.key;
            node.valueList = this.valueList;
            return node;
        }
    }

    /****
     * 比较键位
     * @param targetKey 比较的目标
     * @return 比较结果
     */
    public int compareKey(K targetKey, Comparator<K> keyComparator) {
        Objects.requireNonNull(targetKey, " 目标比较key不可以为null");
        if (Objects.nonNull(keyComparator)) {
            return keyComparator.compare(this.key, targetKey);
        } else {
            if (this.key instanceof Comparable) {
                Comparable<K> keyComparable = (Comparable<K>) this.key;
                return keyComparable.compareTo(targetKey);
            } else {
                throw new UnsupportedOperationException("当前键不可以比较");
            }
        }
    }

    public void add(V value) {
        this.valueList.add(value);
    }

    /***
     * 比较节点的key
     * @param targetNode 目标节点
     * @return 比较节点
     */
    public int compareNodeKey(BinarySearchTreeNode<K, V> targetNode) {
        Objects.requireNonNull(targetNode, "企图的节点不可以为null");
        return this.compareKey(targetNode.key, null);
    }

    /***
     * 比较节点的key
     * @param targetNode 目标节点
     * @return 比较节点
     */
    public int compareNodeKey(BinarySearchTreeNode<K, V> targetNode, Comparator<K> keyComparator) {
        Objects.requireNonNull(targetNode, "企图的节点不可以为null");
        return this.compareKey(targetNode.key, keyComparator);
    }

    public boolean isLeaf() {
        return this.getLeft() == null && this.getRight() == null;
    }

    private boolean hasLeftOrRightNull() {
        return this.getLeft() == null || this.getRight() == null;
    }

    public K getKey() {
        return key;
    }

    public List<V> getValueList() {
        return valueList;
    }

    public BinarySearchTreeNode<K, V> getLeft() {
        return left;
    }

    public BinarySearchTreeNode<K, V> getRight() {
        return right;
    }

    public void setKey(K key) {
        this.key = key;
    }

    public void setValueList(List<V> valueList) {
        this.valueList = valueList;
    }

    public void setLeft(BinarySearchTreeNode<K, V> left) {
        this.left = left;
    }

    public void setRight(BinarySearchTreeNode<K, V> right) {
        this.right = right;
    }
}
